﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ShopB2C.Entity;

namespace ShopB2C.Helper {
    /// <summary>
    /// 分类填充 DropDownList 类
    /// </summary>
    internal class ClassifyTree {

        private string _selectedValue, _selectOptions;
        private bool[] _parentEndFlag;
        private List<ClassifyEntity> _classesList;
        private List<object> _itemsList;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="classesList">填充到 DropDownList 的分类集合</param>
        /// <param name="selectedValue">当前选择的 Item</param>
        public ClassifyTree(List<ClassifyEntity> classesList, string selectedValue) {
            this._itemsList = new List<object>();
            this._parentEndFlag = new bool[] { };
            this._classesList = classesList;
            this._selectedValue = selectedValue;
            this._selectOptions = string.Empty;
        }
        /// <summary>
        /// 获取分类的列表
        /// </summary>
        /// <param name="isAddDefault">是否加入默认的项</param>
        /// <returns>SelectList</returns>
        public SelectList CreateSelectList(bool isAddDefault) {
            if (isAddDefault) {
                this._itemsList.Add(new { Text = "顶级分类", Value = "0" });
            }
            if (this._classesList != null) {
                this.AddItemsToList(0, true);
            }
            return new SelectList(this._itemsList, "Value", "Text", this._selectedValue);
        }
        /// <summary>
        /// 获取分类的 option 字符串组合
        /// </summary>
        /// <param name="isAddDefault">是否加入默认的项</param>
        /// <returns>string</returns>
        public string CreateSelect(bool isAddDefault) {
            string result = string.Empty;

            if (this._classesList != null) {
                this.AddItemsToList(0, true);               
            }

            if (isAddDefault) {
                result += "<option selected=\"selected\" value=\"0\">顶级分类</option>";
            }

            return result + this._selectOptions;
        }

        // 添加指定数量的空格
        private string Echalon(int num) {
            string result = string.Empty;
            string nbsp = HttpUtility.HtmlDecode("&nbsp;");
            for (int i = 0; i < num; i++) { result += nbsp; }
            return result;
        }
        // 重定义数组长度
        private bool[] ReDim(int newSize) {
            bool[] newArray = new bool[newSize];
            if (this._parentEndFlag.Length > 0) {
                Array.Copy(this._parentEndFlag, 0, newArray, 0, newSize - 1);
            }

            return newArray;
        }
        // 需要的列表项或字符串
        private void AddItemsToList(int parentClassifyId, bool flag) {
            const string option = "<option value=\"{1}\"{2}{3}>{0}</option>";

            string normalStr = this.Echalon(2) + "├";
            string joinStr = this.Echalon(2) + "│";
            string endStr = this.Echalon(2) + "└";
            string spaceStr = this.Echalon(5);
            bool curFlag = false;
            int i = 0;
            var curList = this._classesList.Where(c => {
                return c.ParentClassifyId == parentClassifyId;
            });
            int count = curList.Count();
            string sT, sE, text, value;

            if (count > 0) {
                foreach (ClassifyEntity ce in curList) {
                    sT = sE = string.Empty;
                    curFlag = i++ + 1 == count;
                    if (ce.Floor > 0) {
                        this._parentEndFlag = this.ReDim(ce.Floor + 1);
                        this._parentEndFlag[ce.Floor] = flag;
                    }
                    else {
                        sT = curFlag ? endStr : normalStr;
                    }

                    for (int ii = 1; ii <= ce.Floor; ii++) {
                        sE += this._parentEndFlag[ii] ? spaceStr : joinStr;
                    }

                    if (ce.Floor > 0) {
                        sT = sE + (curFlag ? endStr : normalStr);
                    }

                    text = sT + this.Echalon(1) + ce.Title;
                    value = ce.ClassifyId.ToString();
                    this._itemsList.Add(new { Text = text, Value = value });
                    this._selectOptions += string.Format(option, text, value,
                        ce.Childs > 0 ? " disabled=\"disabled\"" : string.Empty,
                        this._selectedValue == value ? " selected=\"selected\"" : string.Empty);

                    if (ce.Childs > 0) {
                        this.AddItemsToList(ce.ClassifyId, curFlag);
                    }
                }
            }
        }        
    }
}
